/*---------------------------------------------------------
  Oren Attia  - 
  Doron Segal - 
  ---------------------------------------------------------*/

#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#include "list.h"

typedef struct figure_
{
	int			sUndoFlag;
	int			sFigure;
	int			sMoved;
	int			sFillFlag;
	COLORREF	sColor;
	POINT		sPoint1, sPoint2;
}FigureElmt;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

FigureElmt *CreateFigure(POINT prmPoint1, POINT prmPoint2, int pShape,COLORREF pColor);
FigureElmt *IsFigureExist(int xStart, int yStart);
void DrawFigure(HDC hdc,FigureElmt *pFigure);
void DrawFigureAll(HDC hdc, List *pList);

BOOL LoadFile(HWND hEdit, LPCTSTR pszFileName);
BOOL SaveFile(HWND hEdit, LPCTSTR pszFileName);
void DoFileSave(HWND hwnd);
void DoFileOpen(HWND hwnd);

HINSTANCE gHinst;
COLORREF gColor;

const char g_szClassName[] = "PaintBrush_WindowClass";

static int pShape=ID_DRAW_LINE,pFillFlag=0; 
static RECT rcMain,rcClient,rcShape;
static HBRUSH hBrush,holdBrush ;
static HPEN hPen,holdPen ;

List		list;
ListElmt	*pElement;
FigureElmt	*pFigure;

FigureElmt  *pfMoved = NULL;  
//Element *mainList = NULL,*pe;
POINT  pStartMoved;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	//InitCommonControls();

	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = CS_HREDRAW | CS_VREDRAW ;
	wc.lpfnWndProc	 = WndProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_PAINT));
	wc.hCursor		 = LoadCursor(gHinst, IDC_CROSS);
	wc.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(128,180,200)); //(HBRUSH) GetStockObject (WHITE_BRUSH);
	wc.lpszMenuName  = NULL;											
	wc.lpszClassName = g_szClassName;
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

	gHinst = hInstance;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(
		0,
		g_szClassName,
		"HIT Final Project - Paint Brush Application",
		WS_OVERLAPPEDWINDOW ,
		CW_USEDEFAULT, CW_USEDEFAULT, 625,530,
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);


	list_init(&list, free);
	pElement = list_head(&list);

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int   cxIcon, cyIcon, x, cxClient, y, cyClient, isPressed=0, isCreate = 0;
	static HWND hSelection;
	static HICON hIcon ;

    HDC         hdc = (HDC) wParam ;
	HINSTANCE   hInstance ;
	HWND hTool,hStatus,hDefaultColor,hDefaultMode,hDefaultShape;	
    PAINTSTRUCT ps,psSelection ;
	RECT		rcColors;
	POINT		pPoint1,pPoint2;

	switch(msg)
	{
	 case WM_CREATE:
		 {
			HFONT hfDefault;
			TBBUTTON tbb[6];
			TBADDBITMAP tbab;

			int statwidths[] = {100, -1};


			hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
			hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_PAINT)) ;
			cxIcon = GetSystemMetrics (SM_CXICON) ;
			cyIcon = GetSystemMetrics (SM_CYICON) ;


			// Create Selection SubWindow
			hSelection = CreateWindow (TEXT ("static"),"SelectionWindow",WS_CHILD | WS_VISIBLE | SS_WHITERECT | WS_BORDER,0, 0, 0, 0,hwnd, (HMENU) 9, hInstance, NULL) ;


			// Create Toolbar
			hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
				hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
			if(hTool == NULL)
				MessageBox(hwnd, "Could not create tool bar.", "Error", MB_OK | MB_ICONERROR);

			// Send the TB_BUTTONSTRUCTSIZE message, which is required for
			// backward compatibility.
			SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON),0);
			
			tbab.hInst = HINST_COMMCTRL;
			tbab.nID = IDB_STD_LARGE_COLOR;
			SendMessage(hTool, TB_ADDBITMAP,8, (LPARAM)&tbab);

			ZeroMemory(tbb, sizeof(tbb));
			tbb[0].iBitmap = STD_FILENEW;
			tbb[0].iString = "Clear";
			tbb[0].fsState = TBSTATE_ENABLED;
			tbb[0].fsStyle = TBSTYLE_BUTTON;
			tbb[0].idCommand = ID_CLEAR;

			tbb[1].iBitmap = STD_FILEOPEN;
			tbb[1].iString = "Open";
			tbb[1].fsState = TBSTATE_ENABLED;
			tbb[1].fsStyle = TBSTYLE_BUTTON;
			tbb[1].idCommand = ID_FILE_OPEN;

			tbb[2].iBitmap = STD_FILESAVE;
			tbb[2].iString = "Save";
			tbb[2].fsState = TBSTATE_ENABLED;
			tbb[2].fsStyle = TBSTYLE_BUTTON;
			tbb[2].idCommand = ID_FILE_SAVEAS;

			tbb[3].iBitmap = STD_UNDO;
			tbb[3].iString = "Undo";
			tbb[3].fsState = TBSTATE_ENABLED;
			tbb[3].fsStyle = TBSTYLE_BUTTON;
			tbb[3].idCommand = ID_UNDO;

			tbb[4].iBitmap = STD_REDOW;
			tbb[4].iString = "Redo";
			tbb[4].fsState = TBSTATE_ENABLED;
			tbb[4].fsStyle = TBSTYLE_BUTTON;
			tbb[4].idCommand = ID_REDO;

			tbb[5].iBitmap = NULL_BRUSH;
			tbb[5].iString = "Exit";
			tbb[5].fsState = TBSTATE_ENABLED;
			tbb[5].fsStyle = TBSTYLE_BUTTON;
			tbb[5].idCommand = ID_EXIT;

			SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);


			// Create Status bar
			hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
				WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
				hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);

			SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
			SendMessage(hStatus, SB_SETTEXT,0, (LPARAM)"Paint Brush Status");



			// Create Choose Shape Windows
			CreateWindow(TEXT("button"), TEXT("Choose Shape:"), WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,2, 55,110, 115, hwnd, (HMENU) ID_CHOOSE_SHAPE, gHinst, NULL);
			
			hDefaultShape=CreateWindow(TEXT("button"), TEXT("Line"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,7, 80, 100, 25, hwnd, (HMENU)ID_DRAW_LINE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Square"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,7, 110, 100, 25, hwnd, (HMENU)ID_DRAW_SQUARE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Ellipse"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,7, 140, 100, 25, hwnd, (HMENU)ID_DRAW_ELLIPSE , gHinst, NULL);
			SendMessage(hDefaultShape, BM_SETCHECK,BST_CHECKED,1);

			// Create Choose Fill Shape Windows
			CreateWindow(TEXT("button"), TEXT("Shape Mode:"), WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,2, 170,110, 80, hwnd, (HMENU) ID_CHOOSE_SHAPE, gHinst, NULL);
			
			hDefaultMode=CreateWindow(TEXT("button"), TEXT("Empty Shape"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,7, 190, 100, 25, hwnd, (HMENU)ID_EMPTY_SHAPE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Fill Shape"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,7, 220, 100, 25, hwnd, (HMENU)ID_FILL_SHAPE , gHinst, NULL);
			SendMessage(hDefaultMode, BM_SETCHECK ,BST_CHECKED,1);

			// Create Choose Colors Windows
			CreateWindow(TEXT("button"), TEXT("Choose Color:"), WS_CHILD | WS_VISIBLE | BS_GROUPBOX,2, 250,110, 180, hwnd, (HMENU) ID_CHOOSE_COLOR, gHinst, NULL);

			hDefaultColor = CreateWindow(TEXT("button"), TEXT("Black"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON ,7, 265, 100, 25, hwnd, (HMENU)IDC_BLACK , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Blue"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON  ,7, 285, 100, 25, hwnd, (HMENU)IDC_BLUE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Green"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 305, 100, 25, hwnd, (HMENU)IDC_GREEN , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Cyan"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON ,7, 325, 100, 25, hwnd, (HMENU)IDC_CYAN , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Red"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BN_CLICKED ,7, 345, 100, 25, hwnd, (HMENU)IDC_RED , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Magenta"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 365, 100, 25, hwnd, (HMENU)IDC_MAGENTA , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Yellow"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 385, 100, 25, hwnd, (HMENU)IDC_YELLOW , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("White"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON  ,7, 405, 100, 25, hwnd, (HMENU)IDC_WHITE , gHinst, NULL);

			SendMessage(hDefaultColor, BM_SETCHECK, BST_CHECKED,1);
		 }
		 break;
     case WM_CTLCOLORSTATIC: 
		 {   
			 //SetBkMode( hdc, TRANSPARENT ); 
			 SetBkColor(hdc,RGB(255,255,255));
			 SetTextColor( hdc, RGB( 0,0,0 ) );   
			 return ( INT_PTR )GetStockObject( HOLLOW_BRUSH); 
		 }
		 break;
     case WM_LBUTTONDOWN:
		 {  
		  cxClient=x=LOWORD(lParam);
		  cyClient=y=HIWORD(lParam);
		  if ( pfMoved = IsFigureExist(cxClient,cyClient) )
		  {
			  pfMoved->sMoved = 1;
			  pStartMoved.x = cxClient;  pStartMoved.y = cxClient;
		  }
		  else
			  isPressed=1;
		  
		  InvalidateRect(hwnd,&rcShape,TRUE);
		 }
		 break;
     case WM_MOUSEMOVE:
		 {
		  if(isPressed)
		  {
			  x=LOWORD(lParam);
			  y=HIWORD(lParam);

			  isCreate = 1;
			  InvalidateRect(hwnd,NULL,TRUE);
		  }
		  if(pfMoved)
		  {
			  int dx = LOWORD(lParam) - pStartMoved.x;
			  int dy = HIWORD(lParam) - pStartMoved.y;
			  pfMoved->sPoint1.x += dx; pfMoved->sPoint1.x += dx;
			  pfMoved->sPoint2.y += dy; pfMoved->sPoint2.y += dy;
			  pStartMoved.x = LOWORD(lParam);  pStartMoved.y = HIWORD(lParam);
			  InvalidateRect(hwnd,NULL,FALSE);
		  }
		 }
		 break;
     case WM_LBUTTONUP:
		 {
			isPressed=0; isCreate = 1;
			pPoint1.x = cxClient; pPoint1.y = cyClient;
			pPoint2.x = x; pPoint2.y = y;
			if ( pfMoved == NULL)
			{   		
				pFigure = CreateFigure(pPoint1,pPoint2,pShape,gColor);
				
				list_ins_next(&list,list_tail(&list),pFigure);

				pElement = list_head(&list);
			}
			pfMoved = NULL;
		 }
	     break;
	 case WM_GETMINMAXINFO:
		 {
			LPMINMAXINFO pMMI = (LPMINMAXINFO)lParam;
			pMMI->ptMinTrackSize.x = 625;
			pMMI->ptMinTrackSize.y = 530;
		 }
		 break;
	 case WM_SIZE:
		 {
			HWND hTool;
			RECT rcTool;
			int iToolHeight;

			HWND hStatus;
			RECT rcStatus;
			int iStatusHeight;

			RECT rcClient;

			cxClient = LOWORD (lParam) ;
			cyClient = HIWORD (lParam) ;

			// Size of rcMain main window
			GetWindowRect(hwnd, &rcMain);

			// Size Selection Window
			MoveWindow (hSelection, 0, 0, 115, 433, TRUE) ;


			// Size toolbar and get height
			hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL);
			SendMessage(hTool, TB_AUTOSIZE, 0, 0);

			GetWindowRect(hTool, &rcTool);
			iToolHeight = rcTool.bottom - rcTool.top;


			// Size status bar and get height
			hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS);
			SendMessage(hStatus, WM_SIZE, 0, 0);

			GetWindowRect(hStatus, &rcStatus);
			iStatusHeight = rcStatus.bottom - rcStatus.top;
		 }
	     break;
	 case WM_PAINT: 
		 {
			hdc = BeginPaint (hwnd, &ps) ;

			//for (y = 0 ; y < cyClient ; y += cyIcon)
			//   for (x = 0 ; x < cxClient ; x += cxIcon)
			//		DrawIcon (hdc, x, y, hIcon);		
					
			hBrush = CreateSolidBrush(gColor);
			hPen = CreatePen(PS_SOLID, 5, RGB(255,255,255));
			holdBrush = (HBRUSH) SelectObject(hdc, hBrush);
			holdPen = SelectObject(hdc, hPen);

			Rectangle(hdc, 0, 435, 112.5, 470);		

			SelectObject(hdc, holdBrush);
			SelectObject(hdc, holdPen);

			DeleteObject(holdPen);
			DeleteObject(holdBrush);
			DeleteObject(hPen);
			DeleteObject(hBrush);

			if (isCreate)
			{
				pPoint1.x = cxClient; pPoint1.y = cyClient;
				pPoint2.x = x; pPoint2.y = y;

				pFigure = CreateFigure(pPoint1,pPoint2,pShape,gColor);
				
				DrawFigure(hdc, pFigure);

				DrawFigureAll(hdc,&list);
			}
			
			EndPaint (hwnd, &ps) ;
		 }
	     break;
	 case WM_DRAWITEM :
		 {
		 }
	     break;
	 case WM_CLOSE:
		 {
			 DestroyWindow(hwnd);
		 }
		 break;
	 case WM_DESTROY:
		 {
			 PostQuitMessage(0); 
		 }
		 break;
	 case WM_COMMAND:
		 {
			 switch(LOWORD(wParam))
			 {
				case ID_CLEAR:   
					
				break;
				case ID_FILE_OPEN:
					DoFileOpen(hwnd);
				break;
				case ID_FILE_SAVEAS:
					DoFileSave(hwnd);
				break;
				case ID_UNDO:
					if(list.size > 0)
					{
						pFigure = list.tail;
						pFigure->sUndoFlag=0;
isCreate=0;						
						//hdc = BeginPaint (hwnd, &ps) ;
//RedrawWindow(hwnd,0,0,RDW_INVALIDATE);
						
InvalidateRect(hwnd, NULL, TRUE);

DrawFigureAll(hdc,&list);
						//EndPaint (hwnd, &ps);
isCreate=1;	
					}
				break;
				case ID_REDO:
					if(list.size > 0)
					{
						pFigure  = pElement->data;
						pFigure->sUndoFlag=1;

						DrawFigureAll(hdc,&list);
					}
				break;
				case ID_FILL_SHAPE:
					pFillFlag=1;
				break;
				case ID_EMPTY_SHAPE:
					pFillFlag=0;
				break;
				case ID_DRAW_LINE:
					pShape=ID_DRAW_LINE;
				break; 
				case ID_DRAW_SQUARE:
					pShape=ID_DRAW_SQUARE;
				break; 
				case ID_DRAW_ELLIPSE:
					pShape=ID_DRAW_ELLIPSE;
				break; 
				case ID_EXIT:
					SendMessage(hwnd,WM_CLOSE,0,0L);
				break; 
			 }

			if (HIWORD(wParam) == BN_CLICKED) 
			{
				switch (LOWORD(wParam)) 
				{
					case IDC_BLACK:
						gColor = RGB(0, 0, 0);
					break; 
					case IDC_BLUE:
						gColor = RGB(0, 76, 255);
					break; 
					case IDC_GREEN:
						gColor = RGB(34, 139, 34);
					break; 
					case IDC_CYAN:
						gColor = RGB(0, 255, 255);
					break; 
					case IDC_RED:
						gColor = RGB(255, 0, 0);
					break; 
					case IDC_MAGENTA:
						gColor = RGB(255, 0, 255);
					break; 
					case IDC_YELLOW:
						gColor = RGB(255, 255, 0);
					break; 
					case IDC_WHITE:
						gColor = RGB(255, 255, 255);
					break; 
				}
				InvalidateRect(hwnd, &rcShape, FALSE);
			}
		 }
		 break;		
	 default:
		 return DefWindowProc(hwnd, msg, wParam, lParam);
	}

return 0;
}



FigureElmt *CreateFigure(POINT prmPoint1, POINT prmPoint2, int pShape,COLORREF pColor)
{
	FigureElmt *tmpFigure = (FigureElmt *) malloc(sizeof(FigureElmt)); 
			tmpFigure->sUndoFlag = 1;
			tmpFigure->sPoint1	 = prmPoint1;
			tmpFigure->sPoint2   = prmPoint2;
			tmpFigure->sMoved	 = 0;
			 
			tmpFigure->sFigure   = pShape;
			tmpFigure->sFillFlag = pFillFlag;
			tmpFigure->sColor	 = pColor;

	return tmpFigure;
}
void DrawFigure(HDC hdc, FigureElmt *pFigure)
{  
	  RECT  rcRect;
	  HPEN hPen;
	  HBRUSH hBrush ;
	  LOGBRUSH logBrush;
	  //GetDlgItemText(hEditr,ID_EDITR, redstr, 3);

		if(!(pFigure->sFillFlag))
		{
			hBrush = CreateBrushIndirect(&logBrush);
			//hPen = CreatePen(PS_DOT,  2, BLACK_PEN);
			//holdBrush = (HBRUSH) SelectObject(hdc,NULL_BRUSH); 
			//holdPen = SelectObject(hdc, NULL_PEN);
		}
		else
		{
			hBrush = CreateSolidBrush(pFigure->sColor);
			//hPen = CreatePen(PS_SOLID, 2, BLACK_PEN);
			//holdBrush = (HBRUSH) SelectObject(hdc, hBrush);
			//holdPen = SelectObject(hdc, hPen);
		}

		SelectObject(hdc, hBrush);
		//SelectObject(hdc, holdPen);

		switch(pFigure->sFigure)
		{
		case ID_DRAW_SQUARE:
		  rcRect.left = pFigure->sPoint1.x; rcRect.top = pFigure->sPoint1.y;
		  rcRect.right = pFigure->sPoint2.x; rcRect.bottom = pFigure->sPoint2.y;

		  if(pFigure->sFillFlag)
			   FillRect(hdc,&rcRect,hBrush );
			  
		  Rectangle(hdc,pFigure->sPoint1.x,pFigure->sPoint1.y,pFigure->sPoint2.x,pFigure->sPoint2.y);

		  break;
		case ID_DRAW_ELLIPSE:
		  
		  Ellipse(hdc,pFigure->sPoint1.x,pFigure->sPoint1.y,pFigure->sPoint2.x,pFigure->sPoint2.y);
		  
		  break;
		default: //ID_DRAW_LINE
		  MoveToEx(hdc,pFigure->sPoint1.x,pFigure->sPoint1.y,NULL);
		  LineTo(hdc,pFigure->sPoint2.x,pFigure->sPoint2.y);
		  break;
		}	

		//if(pFillFlag)
		//{
		//	DeleteObject(hPen);
		//	DeleteObject(hBrush);
		//}
		//DeleteObject(holdPen);
		DeleteObject(hBrush);
}



FigureElmt *IsFigureExist(int xStart, int yStart)
{
	//Element  *pe;
	//for( pe = List; pe; pe=pe->next)
	//{
	//	if ( pe->data->typeFigure == LINE && CheckOnLine(pe->data, xStart, yStart) )
	//		return pe->data;
	//	if ( pe->data->typeFigure == RECTANGLE && CheckInRect(pe->data, xStart, yStart) )
	//		return pe->data;
	//	if ( pe->data->typeFigure == ELLIPSE && CheckInEllipse(pe->data,xStart, yStart) )
	//		return pe->data;
	//}
	return NULL;
}


void DrawFigureAll(HDC hdc, List *pList)
{  
	RECT  rcRect;
	HPEN hPen;
	HBRUSH hBrush ;
	LOGBRUSH logBrush;
	
	ListElmt	*tmpElement;
	FigureElmt  *tmpFigure;

	tmpElement = pList->head;
	tmpFigure  = tmpElement->data;

	while (tmpElement)
	{
		if(tmpFigure->sUndoFlag == FALSE) 
		{
			tmpElement = tmpElement->next;
			if (tmpElement)
				tmpFigure  = tmpElement->data;
			continue;
		}

		if(!(tmpFigure->sFillFlag))
		{
			//SetBkColor(hdc,RGB(128,180,200));
			//SetBkMode(hdc,OPAQUE);
			hBrush = CreateBrushIndirect(&logBrush);
			SetBkMode(hdc,TRANSPARENT);
			

		}
		else
		{
			hBrush = CreateSolidBrush(tmpFigure->sColor);
			SetBkColor(hdc,tmpFigure->sColor);
			SetBkMode(hdc,OPAQUE);
		}

		SelectObject(hdc, hBrush);

		switch(tmpFigure->sFigure)
		{
		case ID_DRAW_SQUARE:
		  rcRect.left = tmpFigure->sPoint1.x; rcRect.top = tmpFigure->sPoint1.y;
		  rcRect.right = tmpFigure->sPoint2.x; rcRect.bottom = tmpFigure->sPoint2.y;

		  if(tmpFigure->sFillFlag)
			  FillRect(hdc,&rcRect,hBrush );

		  Rectangle(hdc,tmpFigure->sPoint1.x,tmpFigure->sPoint1.y,tmpFigure->sPoint2.x,tmpFigure->sPoint2.y);

		  break;
		case ID_DRAW_ELLIPSE:
		  
		  Ellipse(hdc,tmpFigure->sPoint1.x,tmpFigure->sPoint1.y,tmpFigure->sPoint2.x,tmpFigure->sPoint2.y);
		  
		  break;
		default: //ID_DRAW_LINE
		  MoveToEx(hdc,tmpFigure->sPoint1.x,tmpFigure->sPoint1.y,NULL);
		  LineTo(hdc,tmpFigure->sPoint2.x,tmpFigure->sPoint2.y);
		  break;
		}
		tmpElement = tmpElement->next;
		tmpFigure  = tmpElement->data;

		DeleteObject(hBrush);
	}
}
void DoFileOpen(HWND hwnd)
{
	OPENFILENAME ofn;
	char szFileName[MAX_PATH] = "";

	ZeroMemory(&ofn, sizeof(ofn));

	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFilter = "Binary Files (*.bin)\0*.bin\0";
	ofn.lpstrFile = szFileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	ofn.lpstrDefExt = "txt";

	if(GetOpenFileName(&ofn))
	{
		HWND hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
		if(LoadFile(hEdit, szFileName))
		{
			SendDlgItemMessage(hwnd, IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)"Opened...");
			SendDlgItemMessage(hwnd, IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM)szFileName);
		}
	}
}

void DoFileSave(HWND hwnd)
{
	OPENFILENAME ofn;
	char szFileName[MAX_PATH] = "";

	ZeroMemory(&ofn, sizeof(ofn));

	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hwnd;
	ofn.lpstrFilter = "Binary Files (*.bin)\0*.bin\0";
	ofn.lpstrFile = szFileName;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrDefExt = "txt";
	ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;

	if(GetSaveFileName(&ofn))
	{
		HWND hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
		if(SaveFile(hEdit, szFileName))
		{
			SendDlgItemMessage(hwnd, IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)"Saved...");
			SendDlgItemMessage(hwnd, IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM)szFileName);
		}
	}
}

BOOL LoadFile(HWND hEdit, LPCTSTR pszFileName)
{
	HANDLE hFile;
	BOOL bSuccess = FALSE;

	hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, 0, NULL);
	if(hFile != INVALID_HANDLE_VALUE)
	{
		DWORD dwFileSize;

		dwFileSize = GetFileSize(hFile, NULL);
		if(dwFileSize != 0xFFFFFFFF)
		{
			LPSTR pszFileText;

			pszFileText = (LPSTR)GlobalAlloc(GPTR, dwFileSize + 1);
			if(pszFileText != NULL)
			{
				DWORD dwRead;

				if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
				{
					pszFileText[dwFileSize] = 0; // Add null terminator
					if(SetWindowText(hEdit, pszFileText))
						bSuccess = TRUE; // It worked!
				}
				GlobalFree(pszFileText);
			}
		}
		CloseHandle(hFile);
	}
	return bSuccess;
}

BOOL SaveFile(HWND hEdit, LPCTSTR pszFileName)
{
	HANDLE hFile;
	BOOL bSuccess = FALSE;

	hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL,
		CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile != INVALID_HANDLE_VALUE)
	{
		DWORD dwTextLength;

		dwTextLength = GetWindowTextLength(hEdit);
		// No need to bother if there's no text.
		if(dwTextLength > 0)
		{
			LPSTR pszText;
			DWORD dwBufferSize = dwTextLength + 1;

			pszText = (LPSTR)GlobalAlloc(GPTR, dwBufferSize);
			if(pszText != NULL)
			{
				if(GetWindowText(hEdit, pszText, dwBufferSize))
				{
					DWORD dwWritten;

					if(WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL))
						bSuccess = TRUE;
				}
				GlobalFree(pszText);
			}
		}
		CloseHandle(hFile);
	}
	return bSuccess;
}
